"""
生成器：
    1、什么是生成器：
    生活比喻：想象你有一个「魔法盒子」，每次打开盒子，它都会变出一个新的玩具。你不需要事先把所有玩具都装进去，而是按需生成。这个盒子就是生成器！
    Python中的定义：生成器是一种惰性计算的迭代器，可以动态生成值，而不是一次性存储所有数据。
    在 Python 中，使用了 yield 的函数被称为生成器（generator）。
    yield 是一个关键字，用于定义生成器函数，生成器函数是一种特殊的函数，可以在迭代过程中逐步产生值，而不是一次性返回所有结果。
    跟普通函数不同的是，生成器是一个返回迭代器的函数，只能用于迭代操作，更简单点理解生成器就是一个迭代器。
    当在生成器函数中使用 yield 语句时，函数的执行将会暂停，并将 yield 后面的表达式作为当前迭代的值返回。
    然后，每次调用生成器的 next() 方法或使用 for 循环进行迭代时，函数会从上次暂停的地方继续执行，直到再次遇到 yield 语句。这样，生成器函数可以逐步产生值，而不需要一次性计算并返回所有结果。
    调用一个生成器函数，返回的是一个迭代器对象。

    2、为什么需要生成器？
    核心优势：节省内存
        假设你要处理一个包含100万条数据的文件：
        传统列表：一次性加载全部数据 → 内存爆炸
        生成器：逐行读取，每次只处理一行 → 内存友好
    适用场景：
        处理超大文件（如日志文件）
        生成无限序列（如斐波那契数列）
        数据流处理（如实时传感器数据）

    3、创建生成器的两种方法
    方法1：生成器函数（用 yield 关键字）
    yield 的作用：暂停函数执行，返回一个值，下次从暂停处继续。
    方法2：生成器表达式（类似列表推导式）
    语法：用 () 代替 []

    4、生成器 vs 普通函数的区别
    特性	              普通函数	                   生成器函数
    返回值	     用 return 返回一次结果         用 yield 多次返回值
    状态保存     	每次调用重新执行	            记住上次执行位置
    内存占用	       可能占用大量内存                    极低
"""

# 创建生成器的两种方法
# 方法1：
def magic_box():
    yield "a"  # 第一次打开盒子
    yield "b"  # 第二次打开
    yield "c"  # 第三次打开

box = magic_box()  # 创建生成器对象
print(next(box))  # 输出 a
print(next(box))  # 输出 b
print(next(box))  # 输出 c

# 方法2：
# 列表推导式-》立即生成所有数据
numbers_list = [x * 2 for x in range(3)]
print(numbers_list)  # [0, 2, 4]

# 生成器表达式-》按需生成数据
numbers_gen = (x * 2 for x in range(3))
print(next(numbers_gen))  # [0]
print(next(numbers_gen))  # [2]
